老鼠走迷宫问题

参考http://caterpillar.onlyfun.net/Gossip/AlgorithmGossip/MouseGoMaze.htm

问题有一个迷宫,在迷宫的某个出口放着一块奶酪。将一只老鼠由某个入口处放进去,它必须穿过迷宫,找到奶酪。请找出它的行走路径。

解法:这个问题可以用递归的方法去求解。

        先来看下面这幅图:

        绿色箭头指向的是迷宫的入口,将小老鼠由此放入,红色箭头的位置就是奶酪的所在地,小老鼠必须穿过迷宫从红色箭头标示的地方走出去。

我们用一个二维数组来表示迷宫,用2表示迷宫的墙壁,即上图中的黑色部分,用0表示通路,即上图中老鼠可以行走空白的格子。老鼠每走到一个格子的时候就将该位置的值置为1,表示老鼠的行走路径包括这个格子。

        接下来说一下老鼠的行走策略:老鼠每走一步(格子)的时候,将该格子的值置为1,然后会依次考察该格子的右、下、左、上位置的格子是否可走(可走的标志是该格子的值为0)。这样老鼠从入口的格子出发,就会派生出很多可能的行走路径,如果某一条路不能走到终点的话,那么就要将相应的格子的值重新置为0了,表示正确的路径不包括这个格子。

        好了,终于到具体的实现代码了:

public class Mouse {

	public static void main(String[] args) {
		
		int[][] maze={{2,2,2,0,2,2,2,0,0},
				      {2,0,0,0,0,0,2,0,0},
				      {2,0,2,2,2,2,2,2,2},
				      {0,0,0,0,0,0,0,0,2},
				      {2,0,2,2,2,2,0,2,2},
				      {2,0,2,2,0,0,0,2,2},
				      {2,0,2,2,0,2,2,0,2},
				      {2,0,2,0,0,0,0,0,0},
				      {2,0,2,2,2,2,2,2,2}		
		             };
		Map map=new Map(maze, new Point(7, 8));
		Mouse.go(map, new Point(0,3));
		map.print();
	
	}
	public static void go(Map map,Point p){
		
		   map.step(p);
		   if(p.y<map.maze[0].length-1)
		   {
			   test(map,new Point(p.x, p.y+1));
		   }
		   if(p.x<map.maze.length-1)
		   {
			   test(map,new Point(p.x+1, p.y));
		   }
		   if(p.y>=1)
		   {
			   test(map,new Point(p.x, p.y-1));
		   }
		   if(p.x>=1)
		   {
			   test(map,new Point(p.x-1, p.y));
		   }
		   if(!map.isArrived())
			   map.empty(p);
	}
   public static void test(Map map,Point p){
		
		if(!map.isArrived() && map.isEmpty(p)){
			go(map,p);
		}
	}		
}

class Point{
	
	int x;
	int y;
	public Point(int x1,int y1){
		
		x=x1;
		y=y1;
	}
}
class Map{
	
	int[][] maze;
	Point end;    //终点
	public Map(int[][] maze,Point end){
		
		this.maze=maze;
		this.end=end;
		
	}
	//是否到达终点
	public boolean isArrived(){
		
		return maze[end.x][end.y]==1;
		
	}
	//当前这一格是否可行
	public boolean isEmpty(Point p){
		
		  return maze[p.x][p.y]==0;
	}
	//可以理解为当经过Point p 无法走到终点时,把老鼠走过的痕迹抹去,表示最终的走法不含p
	public void empty(Point p){
		
		maze[p.x][p.y]=0;
		
	}
	//走到Point p
	public void step(Point p){
		
			maze[p.x][p.y]=1;
		
	}
	//打印地图,含老鼠走过的路径
	public void print(){
		for(int i=0;i<maze.length;i++)
		 {
			for(int j=0;j<maze[0].length;j++)
			    if(maze[i][j]==2){
			    	 System.out.print("█");
			    }else if(maze[i][j]==0){
			    	System.out.print(" ");
			    }else if(maze[i][j]==1){
			    	System.out.print("1");
			    }
			System.out.println();	
		 }
		
	}
    	
}

       运行结果如下:


可见,小老鼠成功地走到了终点。

        如果迷宫的设计使得走法不止一种,则只要在老鼠走至出口时显示出所有的路径,然后退回上一格重新选择下一个位置继续递归就可以了。如下图有两种走法。

代码作了一点点儿修改:

public class Mouse {

	public static void main(String[] args) {
		
		int[][] maze={{2,2,2,0,2,2,2,0,0},
				      {2,0,0,0,0,0,2,0,0},
				      {2,0,2,2,2,0,2,2,2},
				      {0,0,0,0,0,0,0,0,2},
				      {2,0,2,2,2,2,0,2,2},
				      {2,0,2,2,0,0,0,2,2},
				      {2,0,2,2,0,2,2,0,2},
				      {2,0,2,0,0,0,0,0,0},
				      {2,0,2,2,2,2,2,2,2}		
		             };
		Map map=new Map(maze, new Point(7, 8));
		Mouse.go(map, new Point(0,3));
		//map.print();
	
	}
	public static void go(Map map,Point p){
		
		   map.step(p);
		   if(map.isArrived())
		   {
			   map.print();
			   map.maze[map.end.x][map.end.y]=0;
		   }
			   
		   if(p.y<map.maze[0].length-1)
		   {
			   test(map,new Point(p.x, p.y+1));
		   }
		   if(p.x<map.maze.length-1)
		   {
			   test(map,new Point(p.x+1, p.y));
		   }
		   if(p.y>=1)
		   {
			   test(map,new Point(p.x, p.y-1));
		   }
		   if(p.x>=1)
		   {
			   test(map,new Point(p.x-1, p.y));
		   }
		   
			   map.empty(p);
	}
   public static void test(Map map,Point p){
		
		if(!map.isArrived() && map.isEmpty(p)){
			go(map,p);
		}
	}		
}

class Point{
	
	int x;
	int y;
	public Point(int x1,int y1){
		
		x=x1;
		y=y1;
	}
}
class Map{
	
	int[][] maze;
	Point end;    //终点
	public Map(int[][] maze,Point end){
		
		this.maze=maze;
		this.end=end;
		
	}
	//是否到达终点
	public boolean isArrived(){
		
		return maze[end.x][end.y]==1;
		
	}
	//当前这一格是否可行
	public boolean isEmpty(Point p){
		
		  return maze[p.x][p.y]==0;
	}
	//可以理解为当经过Point p 无法走到终点时,把老鼠走过的痕迹抹去,表示最终的走法不含p
	public void empty(Point p){
		
		maze[p.x][p.y]=0;
		
	}
	//走到Point p
	public void step(Point p){
		
			maze[p.x][p.y]=1;
		
	}
	//打印地图,含老鼠走过的路径
	public void print(){
		for(int i=0;i<maze.length;i++)
		 {
			for(int j=0;j<maze[0].length;j++)
			    if(maze[i][j]==2){
			    	 System.out.print("█");
			    }else if(maze[i][j]==0){
			    	System.out.print(" ");
			    }else if(maze[i][j]==1){
			    	System.out.print("1");
			    }
			System.out.println();	
		 }
		System.out.println();
	}
    	
}


运行结果:

~完~

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用[1]和引用的描述,我们可以得出以下结论: 对于引用中的问题老鼠迷宫坍塌之前逃生的概率可以通过计算老鼠逃生路径的数量与总路径数量的比值来得到。假设迷宫中共有n个格子,则老鼠逃生路径的数量为n-1,总路径数量为4^(n-1)。因此,老鼠迷宫坍塌之前逃生的概率为(n-1)/(4^(n-1))。 如果老鼠的速度提高一倍,即每分钟两格,那么老鼠迷宫坍塌之前逃生的概率会增加多少呢?由于老鼠的速度提高一倍,它在同样的时间内可以的格子数也增加了一倍。因此,老鼠逃生路径的数量也会增加一倍,而总路径数量仍然为4^(n-1)。所以,老鼠迷宫坍塌之前逃生的概率会增加到2*(n-1)/(4^(n-1))。 对于引用中的问题,我们可以使用深度优先搜索(DFS)算法来解决老鼠迷宫问题。具体步骤如下: 1. 创建一个空的路径列表,用于存储老鼠过的路径。 2. 从迷宫的入口开始,将入口添加到路径列表中。 3. 对于当前位置,判断是否为迷宫的出口。如果是,则返回路径列表作为解决方案。 4. 如果当前位置不是出口,则按照顺时针的方向依次尝试向上、向右、向下、向左移动一格。 5. 对于每个移动后的位置,判断是否为合法位置(即不超出迷宫范围且没有墙)。如果是合法位置,则将该位置添加到路径列表中,并递归调用步骤4。 6. 如果所有移动后的位置都不是合法位置,则回溯到上一个位置,将该位置从路径列表中移除,并继续尝试下一个方向的移动。 7. 重复步骤4-6,直到找到解决方案或所有路径都被尝试过。 通过以上步骤,我们可以找到老鼠从入口到奶酪的路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值